﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using XospitalParser.stats;

namespace XospitalParser
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.Error.WriteLine("Invalid argument. Input dir:" +
                                        Assembly.GetExecutingAssembly().ManifestModule.Name + " <dir with logs>");
                Console.ReadKey();
                return;
            }
            string dir = args[0];
            if (!Directory.Exists(dir))
            {
                Console.Error.WriteLine("Directory does not exist: " + dir);
                Console.ReadKey();
                return;
            }
            string[] files = Directory.GetFiles(dir);
            Console.WriteLine("found files: " + files.Length);
            string location = Assembly.GetExecutingAssembly().Location;
            DirectoryInfo directoryInfo = new FileInfo(location).Directory;
            string currentDir = directoryInfo.FullName;
            try
            {
                ProcessFiles(currentDir, files);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                string errorFile = Path.Combine(currentDir, "error.txt");
                using (FileStream fileStream = File.OpenWrite(errorFile))
                {
                    using (var streamWriter = new StreamWriter(fileStream))
                    {
                        streamWriter.WriteLine(e);
                    }
                }
            }
            finally
            {
                Console.ReadKey();
            }
        }

        private static void ProcessFiles(string currentDir, string[] files)
        {
            var logFileParser = new LogFileParser();
            var userActions = new List<UserAction>();
            foreach (string file in files)
            {
                userActions.AddRange(logFileParser.Parse(file));
            }
            Console.WriteLine("total user's actions parsed: " + userActions.Count);
            var userActionStatistics = new UserActionStatistics(userActions);
            SaveStatistics(currentDir, userActionStatistics);
        }

        private static void SaveStatistics(string currentDir, UserActionStatistics statistics)
        {
            ShowActivityStats(currentDir, statistics);
            ShowRegisters(currentDir, statistics);
            ShowIpToUsers(currentDir, statistics);
        }

        private static void ShowActivityStats(string currentDir, UserActionStatistics statistics)
        {
            IDictionary<string, IList<DateInfo>> userActivity = statistics.GetUserActivity();
            string filePath = Path.Combine(currentDir, "usersActivity.txt");
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            using (var streamWriter = new StreamWriter(fileStream))
            {
                streamWriter.WriteLine(
                    "Статистика активности пользователей по дням. В скобках - кол-во вызовов контроллера.\n");
                foreach (var pair in userActivity)
                {
                    string user = pair.Key;
                    IList<DateInfo> dateTimes = pair.Value;
                    streamWriter.WriteLine(user);
                    foreach (DateInfo dateTime in dateTimes)
                    {
                        string str = String.Format("\t{0}  ({1})", dateTime.Date.ToShortDateString(),
                                                   dateTime.AllActivities.Count);
                        streamWriter.WriteLine(str);
                    }
                }
            }

            Console.WriteLine("users total: " + userActivity.Keys.Count);
            Console.WriteLine("everything is OK");
            Console.WriteLine("user activity stats has been saved to:\n" + filePath);
        }

        public static void ShowRegisters(string currentDir, UserActionStatistics statistics)
        {
            IDictionary<DateTime, int> registrations = statistics.GetRegistrations();
            string filePath = Path.Combine(currentDir, "usersRegistrations.txt");
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            using (var streamWriter = new StreamWriter(fileStream))
            {
                streamWriter.WriteLine("Статистика регистраций пользователей (с разными ip).\n");
                foreach (var pair in registrations)
                {
                    DateTime date = pair.Key;
                    int count = pair.Value;
                    streamWriter.WriteLine(String.Format("{0} ({1})", date, count));
                }
            }
            Console.WriteLine("user registrations stats has been saved to:\n" + filePath);
        }

        public static void ShowIpToUsers(string currentDir, UserActionStatistics statistics)
        {
            IDictionary<string, IList<string>> ipToUsers = statistics.IpToUsers();
            string filePath = Path.Combine(currentDir, "IpToUsers.txt");
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            using (var streamWriter = new StreamWriter(fileStream))
            {
                foreach (var pair in ipToUsers)
                {
                    string ip = pair.Key;
                    streamWriter.WriteLine(ip);
                    foreach (string user in pair.Value)
                    {
                        streamWriter.WriteLine("\t" + user);
                    }
                }
            }
        }
    }
}